<template>
  <div class="container">
    <topTitle :titleText="titleText"></topTitle>
    <div class="mainCon">
      <div class="leftBox">
        <div class="cradleHead">
          <div class="title bgcTheme">云台控制</div>
          <div class="cm-videomodules-leftbox-ptzbox">
            <div class="fl cm-videomodules-leftbox-ptzbox-direction">
              <div class="up" @click="PTZControl('TurnUp')"></div>
              <div class="center">
                <div class="left" @click="PTZControl('TurnLeft')"></div>
                <div class="right" @click="PTZControl('TurnRight')"></div>
              </div>
              <div class="bottom" @click="PTZControl('TurnUp')"></div>
            </div>
            <div class="fl cm-videomodules-leftbox-ptzbox-features">
              <div class="video-label">缩放</div>
              <div class="video-features">
                <div
                  class="features-left"
                  @click="PTZControl('ZoomInPicture')"
                ></div>
                <div
                  class="features-right"
                  @click="PTZControl('ZoomOutPicture')"
                ></div>
              </div>
              <div class="video-label">光圈</div>
              <div class="video-features">
                <div
                  class="features-left"
                  @click="PTZControl('AugmentAperture')"
                ></div>
                <div
                  class="features-right"
                  @click="PTZControl('MinishAperture')"
                ></div>
              </div>
              <div class="video-label">聚焦</div>
              <div class="video-features">
                <div
                  class="features-left"
                  @click="PTZControl('MakeFocusFar')"
                ></div>
                <div
                  class="features-right"
                  @click="PTZControl('MakeFocusNear')"
                ></div>
              </div>
            </div>
            <div class="cm-videomodules-leftbox-ptzbox-speedbox">
              <div class="video-label">云台速度</div>
              <div class="video-ptzspeed-box">
                <el-slider
                  v-model="ptzspeed"
                  @change="SetPTZSpeed()"
                ></el-slider>
              </div>
            </div>
          </div>
        </div>
        <div class="treeBox">
          <div class="title bgcTheme">视频监控列表</div>
          <div class="treeCon videopreviewTreeCon">
            <el-tree
              :data="data"
              node-key="id"
              default-expand-all
              :props="defaultProps"
              :expand-on-click-node="false"
              :render-content="renderContent"
              @node-click="handleNodeClick"
              :default-checked-keys="[5]"
            >
            </el-tree>
          </div>
        </div>
      </div>
      <div class="rightBox">
        <div class="windowgroup">
          <ul class="clearfix">
            <li
              v-for="(item, index) of num"
              :key="index"
              :class="{
                oneClass: num == 1,
                fourClass: num == 4,
                nineClass: num == 9,
                sixteenClass: num == 16,
                currentClass: i == index,
              }"
              @mouseover="isShow = index"
              @mouseout="isShow = -1"
              :id="'conBox' + index"
              @click="clickBox(index)"
            >
              <div class="videoBox" :id="'videoBox' + index"></div>
              <!-- 视频名称，关闭 -->
              <div class="cm-videomodule-videomessage" v-show="index == isShow">
                <div class="cm-videomodule-videomessage-message fl">
                  {{
                    videoData[index].videoTitle
                      ? videoData[index].videoTitle
                      : '无视频'
                  }}
                </div>
                <!-- <div class="cm-videomodule-videomessage-message fl" v-else>
                  {{ "无视频" }}
                </div> -->
                <div class="h5c-icons-floatRight h5c-icons-lineHeight fr">
                  <el-tooltip
                    class="item"
                    effect="dark"
                    content="关闭视频"
                    placement="bottom"
                  >
                    <i
                      class="el-dialog__close el-icon el-icon-close"
                      @click="closeVideo(index)"
                    ></i>
                  </el-tooltip>
                </div>
              </div>
              <!-- 窗口视频提示 -->
              <div class="pvideo-window-state">
                {{ videoData[index].showText }}
              </div>
              <!-- 操作 -->
              <div class="cm-videomodule-videocontrol" v-show="index == isShow">
                <template>
                  <!-- 开启音频 -->
                  <div class="h5c-icons-floatLeft h5c-icons-lineHeight">
                    <el-tooltip
                      class="item"
                      effect="dark"
                      :content="
                        videoData[index].isOpenAudio ? '关闭音频' : '开启音频'
                      "
                      placement="bottom"
                    >
                      <i
                        class="icon iconfont iconjingyin"
                        :class="
                          videoData[index].isOpenAudio
                            ? 'icon iconfont iconcancelMute-quxiaojingyin'
                            : 'icon iconfont iconjingyin'
                        "
                        @click="toOpenAudio(index)"
                      ></i>
                    </el-tooltip>
                  </div>
                  <!-- 开启喊话 -->
                  <div class="h5c-icons-floatLeft h5c-icons-lineHeight">
                    <el-tooltip
                      class="item"
                      effect="dark"
                      :content="
                        videoData[index].isOpenCall ? '关闭喊话' : '开启喊话'
                      "
                      placement="bottom"
                    >
                      <i
                        class="icon iconfont iconmic-off-full"
                        :class="
                          videoData[index].isOpenCall
                            ? 'icon iconfont iconmic-on-full'
                            : 'icon iconfont iconmic-off-full'
                        "
                        @click="toOpenCall(index)"
                      ></i>
                    </el-tooltip>
                  </div>
                  <!-- 开启对讲 -->
                  <div class="h5c-icons-floatLeft h5c-icons-lineHeight">
                    <el-tooltip
                      class="item"
                      effect="dark"
                      :content="
                        videoData[index].isOpenTalk ? '关闭对讲' : '开启对讲'
                      "
                      placement="bottom"
                    >
                      <i
                        class="icon iconfont icondianhua"
                        :class="
                          videoData[index].isOpenTalk
                            ? 'icon iconfont icondianhua redIcon'
                            : 'icon iconfont icondianhua'
                        "
                        @click="toOpenTalk(index)"
                      ></i>
                    </el-tooltip>
                  </div>
                </template>
                <!-- 本地抓拍 -->
                <div class="h5c-icons-floatLeft h5c-icons-lineHeight">
                  <el-tooltip
                    class="item"
                    effect="dark"
                    content="本地抓拍"
                    placement="bottom"
                  >
                    <i
                      class="icon iconfont iconxiangji"
                      @click="Snapshot(index)"
                    ></i>
                  </el-tooltip>
                </div>
                <!-- 开启本地录像 -->
                <!-- isActived == index && isOpenRecord -->
                <div class="h5c-icons-floatLeft h5c-icons-lineHeight">
                  <el-tooltip
                    class="item"
                    effect="dark"
                    :content="
                      videoData[index].isOpenRecord
                        ? '关闭本地录像'
                        : '开启本地录像'
                    "
                    placement="bottom"
                  >
                    <i
                      :class="
                        videoData[index].isOpenRecord
                          ? 'icon iconfont iconluxiang-tianchong redIcon'
                          : 'icon iconfont iconluxiang-tianchong'
                      "
                      @click="OpenRecord(index)"
                    ></i>
                  </el-tooltip>
                </div>
                <!-- 本地录像列表 -->
                <div class="h5c-icons-floatLeft h5c-icons-lineHeight">
                  <el-tooltip
                    class="item"
                    effect="dark"
                    content="本地录像列表"
                    placement="bottom"
                  >
                    <i
                      class="icon iconfont iconliebiao"
                      @click="GetH5LocalRecordList(index)"
                    ></i>
                  </el-tooltip>
                </div>
                <!-- 窗口全屏 -->
                <div class="h5c-icons-floatRight h5c-icons-lineHeight">
                  <el-tooltip
                    class="item"
                    effect="dark"
                    content="窗口全屏"
                    placement="bottom"
                  >
                    <i
                      class="icon iconfont icondaping-quanping"
                      @click="fullScreen(index)"
                      v-if="!fullscreen"
                    ></i>
                    <i
                      class="icon iconfont iconguanbiquanping"
                      @click="fullScreen(index)"
                      v-if="fullscreen"
                    ></i>
                  </el-tooltip>
                </div>
              </div>
            </li>
          </ul>
        </div>
        <div class="btngroup">
          <ul class="btnBox clearfix">
            <li @click="changeVideo(1)" :class="num == 1 ? 'active' : ''"></li>
            <li @click="changeVideo(4)" :class="num == 4 ? 'active' : ''"></li>
            <li @click="changeVideo(9)" :class="num == 9 ? 'active' : ''"></li>
            <li
              @click="changeVideo(16)"
              :class="num == 16 ? 'active' : ''"
            ></li>
          </ul>
        </div>
      </div>
    </div>
    <!-- 本地录像列表 -->
    <el-dialog
      title="前端本地录像存储列表"
      width="80%"
      :visible.sync="dialogVisible"
      :before-close="handleClose"
      :modal-append-to-body="false"
    >
      <el-table
        :data="tableData"
        :header-cell-style="{ background: '#eef1f6', color: '#606266' }"
        highlight-current-row
        stripe
        style="border: 1px solid #dfe6ec"
      >
        <el-table-column type="index" label="#" width="50"> </el-table-column>
        <el-table-column prop="PuName" label="设备名称"> </el-table-column>
        <el-table-column prop="ResName" label="资源名称" width="100">
        </el-table-column>
        <el-table-column
          prop="FilePathName"
          label="文件名称"
          :formatter="formatterName"
          min-width="150px"
        >
        </el-table-column>
        <el-table-column prop="BeginTime" label="开始时间"> </el-table-column>
        <el-table-column prop="EndTime" label="结束时间"> </el-table-column>
        <el-table-column label="操作">
          <template slot-scope="scope">
            <el-link type="primary" @click="downLoad(scope.row)">下载</el-link>
          </template>
        </el-table-column>
      </el-table>
      <span slot="footer" class="dialog-footer">
        <el-button @click.native="cancel('formData')" class="cancel"
          >关闭</el-button
        >
        <el-button
          type="primary"
          @click.native="refresh('formData')"
          class="save"
          :loading="canLogin"
          >刷新</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { mapActions, mapState } from 'vuex'

import Ajax from '../../../static/js/js/Ajax.js'
import H5Live from '../../../static/js/h5live-1.0.7.js'

export default {
  name: 'videopreview',
  data() {
    return {
      titleText: '视频监控',
      data: [
        {
          id: 1,
          online: 2,
          name: 'Surveillance System',
          children: [],
        },
      ],
      defaultProps: {
        children: 'children',
        label: 'name',
      },
      value1: 10,
      //   初始化
      _h5live_valided: '', //是否支持
      sessionID: '', //sessionID
      wsPath: '', // websocket地址
      num: 4, //视频窗口数
      videoWindow: [], //视频窗口实例化对象
      isShow: -2, //是否显示视频上的操作按钮
      puid: '', //设备puid
      fullscreen: false, //是否全屏
      ptzspeed: '', //云台速度
      dialogVisible: false,
      canLogin: false,
      isOpenRecord: false, //是否开启本地录像
      tableData: '',
      index: '', //当前视频窗口索引
      videoData: [], //视频数据
      text: '', //视频提示文字
      i: '', //选中色，选中视频窗口
      talkMediaRecorder: '', //对讲实例
      callMediaRecorder: '', //喊话实例
      isActived: -1, //录像窗口ID
      videoArr: [0], // 有视频播放的窗口index集合
      wsOpen: '', //websocket是否连接
    }
  },
  computed: { ...mapState(['areasOptions', 'industryOptions']) },

  created() {
    //检测浏览器是否支持
    this.ValidObjectLoad()
  },
  activated() {},
  methods: {
    renderContent(h, { node, data, store }) {
      if (data.online == '1') {
        return (
          <span class="custom-tree-node">
            <span>{node.label}（在线）</span>
          </span>
        )
      } else if (data.online == '0') {
        return (
          <span class="custom-tree-node">
            <span>{node.label}（离线）</span>
          </span>
        )
      } else {
        return (
          <span class="custom-tree-node">
            <span>{node.label}</span>
          </span>
        )
      }
    },
    ValidObjectLoad() {
      var operator = H5Live.ValidObjectLoad()
      //为0表示支持
      if (operator.rv == 0) {
        this._h5live_valided = true
      } else {
        this._h5live_valided = false
      }
      // 创建窗口实例化对象
      if (this._h5live_valided) {
        this.login()
        // 初始化视频数据
        for (var i = 0; i < this.num; i++) {
          this.videoData[i] = {}
        }
      }
    },
    //登录
    login() {
      var param = {
        userID: 'admin@system',
        password: '',
      }
      var that = this
      Ajax.SendAjax('Connect', param, function (rv) {
        if (rv.errorCode == '0x0000') {
          that.sessionID = rv.content.sessionID
          //获取设备信息
          that.ForkPUResource()
          //获取视频websocket地址
          that.GetWSAddress()
          //获取事件websocket地址
          that.GetWSEventAddress()
        } else {
          that.errorMsg(rv.errorCode)
        }
      })
    },
    // 获取设备信息
    ForkPUResource() {
      var param = {
        sessionID: this.sessionID,
        offset: 0,
        count: 500,
        // DomainRoad: '',  //子域名称（可不传，默认为空）
      }
      var that = this
      Ajax.SendAjax('ForkPUResource', param, function (rv) {
        if (rv.errorCode == '0x0000') {
          // 树结构数据
          var arr = []
          for (var i = 0; i < rv.content.length; i++) {
            if (rv.content[i].modelType == 'WENC') {
              arr.push(rv.content[i])
            }
          }
          that.data[0].children = arr
        } else {
          that.errorMsg(rv.errorCode)
        }
      })
    },
    // 获取子设备信息
    ForkPUResourceNodes(puid, name) {
      var param = {
        sessionID: this.sessionID,
        puid: puid, //需要获取的设备PUID
        puidList: '', //需要获取的设备PUID集合
        //两个参数任意传入一个即可，优先匹配puidList
      }
      var that = this
      Ajax.SendAjax('ForkPUResourceNodes', param, function (rv) {
        if (rv.errorCode == '0x0000') {
          //获取视频窗口的个数
          that.getVideoNum(rv.content, name)
        } else {
          that.errorMsg(rv.errorCode)
        }
      })
    },
    //获取视频窗口的个数
    getVideoNum(content, name) {
      var data = ''
      for (var i = 0; i < content.length; i++) {
        if (content[i].type == 'IV') {
          // this.videoData.push(content[i]);
          data = content[i]
        }
      }
      var index = this.i ? this.i : 0
      this.videoData[index] = data
      this.videoData[index].videoTitle = name
      // this.videoData[index].showText = "设备已上线，视频流尝试重连中...";
      var data = this.videoData[index]
      data.showText = '设备已上线，视频流尝试重连中...'
      this.$set(this.videoData, index, data)
      // for(var i = 0 ; i < this.videoArr.length ; i ++){
      //   var index = this.videoArr[i];
      //   if(JSON.stringify(this.videoData[index])== "{}"){
      //     this.videoData[index] = data;
      //     this.videoData[index].videoTitle =name;
      //     // this.videoData[index].videoTitle =name + "-Camera";
      //   }else{
      //     this.videoData[index] = this.videoData[index];
      //   }
      // }

      // 销毁视频实例
      // this.DestoryWindows();
      // 实例化视频实例
      this.$nextTick(function () {
        var that = this
        setTimeout(function () {
          that.newWindow()
        }, 500)
        // this.newWindow();
      })
    },
    //获取websocket地址
    GetWSAddress() {
      var param = {
        sessionID: this.sessionID,
        Type: 'VIDEO', //WS类型，VIDEO/VOD/GPS/EVENT
        streamType: 'REALTIME', //流类型，REALTIME/STORAGE
      }
      var that = this
      Ajax.SendAjax('GetWSAddress', param, function (rv) {
        if (rv.errorCode == '0x0000') {
          that.wsPath = rv.content.Addr
          // that.DataNotify(rv.content.Addr);
        } else {
          that.errorMsg(rv.errorCode)
        }
      })
    },
    //获取事件websocket地址
    GetWSEventAddress() {
      var param = {
        sessionID: this.sessionID,
        Type: 'EVENT', //WS类型，VIDEO/VOD/GPS/EVENT
        // streamType: "REALTIME", //流类型，REALTIME/STORAGE
      }
      var that = this
      Ajax.SendAjax('GetWSAddress', param, function (rv) {
        if (rv.errorCode == '0x0000') {
          that.DataNotify(rv.content.Addr)
        } else {
          that.errorMsg(rv.errorCode)
        }
      })
    },
    //获取对讲websocket地址
    GetWSVIDEOAddress(index) {
      var param = {
        sessionID: this.sessionID,
        Type: 'VIDEO', //WS类型，VIDEO/VOD/GPS/EVENT
      }
      var that = this
      Ajax.SendAjax('GetWSAddress', param, function (rv) {
        if (rv.errorCode == '0x0000') {
          that.OpenTalk(rv.content.Addr, index)
        } else {
          that.errorMsg(rv.errorCode)
        }
      })
    },
    //获取喊话websocket地址，其实和对讲是同一个方法 ~.~
    GetWSAudioAddress(index) {
      var param = {
        sessionID: this.sessionID,
        Type: 'VIDEO', //WS类型，VIDEO/VOD/GPS/EVENT
      }
      var that = this
      Ajax.SendAjax('GetWSAddress', param, function (rv) {
        if (rv.errorCode == '0x0000') {
          that.OpenCall(rv.content.Addr, index)
        } else {
          that.errorMsg(rv.errorCode)
        }
      })
    },
    //获取系统通知消息
    DataNotify(wsPath) {
      var param = {
        identity: 'admin', //登录系统用户名，默认admin
        epId: 'system', //登录系统epid，默认system
        wsPath: wsPath, //websocket地址
        // mode:'event',
        options: {
          mode: 'event',
        }, //通知模式，分为event（事件通知）和gps（GPS通知）
        callback: notifyCallBack, //回调函数
      }
      var that = this
      var notify = new H5Live.DataNotify(param)
      var that = this
      function notifyCallBack(response) {
        try {
          if (response.action == 'EventNotify') {
            switch (response.data.id) {
              case 'EVT_PU_Offline':
                //下线
                // that.ForkPUResource();
                that.changeTreeState(response.data.srcID, false)
                for (var i = 0; i < that.videoData.length; i++) {
                  if (response.data.srcID == that.videoData[i].puid) {
                    console.log('i:' + i)
                    var data = that.videoData[i]
                    data.showText = '设备已下线，视频流暂停播放'
                    that.$set(that.videoData, i, data)
                  }
                }
                break
              case 'EVT_PU_Online':
                console.log('上线')
                //上线
                // 把当前树结构的状态变更
                that.changeTreeState(response.data.srcID, true)
                var index = ''
                for (var i = 0; i < that.videoData.length; i++) {
                  if (response.data.srcID == that.videoData[i].puid) {
                    index = i
                    var data = that.videoData[i]
                    data.showText = '设备已上线，视频流尝试重连中...'
                    that.$set(that.videoData, i, data)
                  }
                }

                if (index || index == 0) {
                  setTimeout(function () {
                    that.openVideo(index)
                  }, 500)
                }
                break
              case 'EVT_PU_Deleted':
                console.log('EVT_PU_Deleted')
                break
            }
          }
          if (response.action == 'ws.open') {
            console.log(2)
            that.wsOpen = true
            console.log('ws.open')
          }
        } catch (e) {
          // excep('notifyCallBack', e);
        }
      }
    },
    // 改变树结构类型
    changeTreeState(puid, type) {
      var data = this.data[0].children
      for (var i = 0; i < data.length; i++) {
        if (puid == data[i].puid) {
          if (type) {
            this.data[0].children[i].online = '1'
          } else {
            this.data[0].children[i].online = '0'
          }
        }
      }
    },
    // 上线的时候打开视频
    openVideo(index) {
      H5Live.DestoryWindows('videoBox' + index)
      var that = this
      that.$nextTick(function () {
        that.videoWindow[index] = new H5Live.Window('videoBox' + index, {
          callback: H5CallBack,
        })
        // 创建视频窗口,回调
        function H5CallBack(response) {
          that.H5CallBack(response)
        }
        // 开始播放视频
        var param = {
          wsPath: that.wsPath, //websocket地址
          puid: that.videoData[index].puid, //设备puid
          idx: that.videoData[index].idx, //摄像头索引
          streamType: 'REALTIME', //流类型 默认为REALTIME
        }

        that.videoWindow[index].OpenVideo(param)
        // that.videoWindow[index].OpenAudio();
        that.videoData[index].showText = ''
        // var data = that.videoData[index];
        // data.showText = "";
        // that.$set(that.videoData, index , data);
      })
    },
    // 创建视频窗口
    newWindow() {
      var index = this.i ? this.i : 0
      this.openVideo(index)
    },
    // 销毁视频窗口
    DestoryWindows() {
      var that = this
      for (var i = 0; i < that.num; i++) {
        H5Live.DestoryWindows('videoBox' + i)
      }
    },
    //视频窗口个数
    changeVideo(num) {
      this.num = num
      this.i = 0
      // 销毁视频实例
      // this.DestoryWindows();
      // 实例化视频实例
      this.$nextTick(function () {
        this.newWindow(this.puid)
      })

      //实例化窗口数据
      // videoData
      for (var i = 0; i < this.num; i++) {
        if (JSON.stringify(this.videoData[i]) !== '{}') {
          if (this.videoData[i] !== undefined) {
            this.videoData[i] = this.videoData[i]
          } else {
            this.videoData[i] = {}
          }
        } else {
          this.videoData[i] = {}
        }
      }
    },
    // 关闭视频
    closeVideo(index) {
      this.videoData[index] = {}
      // this.videoArr
      for (var i = 0; i < this.videoArr.length; i++) {
        if (this.videoArr[i] == index) {
          this.videoArr.splice(i, 0)
        }
      }

      this.videoWindow[index].CloseVideo()
    },
    // 全屏
    fullScreen(index) {
      var fullarea = document.getElementById('conBox' + index)
      if (this.fullscreen) {
        // 退出全屏
        if (document.exitFullscreen) {
          document.exitFullscreen()
        } else if (document.webkitCancelFullScreen) {
          document.webkitCancelFullScreen()
        } else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen()
        } else if (document.msExitFullscreen) {
          document.msExitFullscreen()
        }
      } else {
        // 进入全屏
        if (fullarea.requestFullscreen) {
          fullarea.requestFullscreen()
        } else if (fullarea.webkitRequestFullScreen) {
          fullarea.webkitRequestFullScreen()
        } else if (fullarea.mozRequestFullScreen) {
          fullarea.mozRequestFullScreen()
        } else if (fullarea.msRequestFullscreen) {
          // IE11
          fullarea.msRequestFullscreen()
        }
      }
      this.fullscreen = !this.fullscreen
    },
    // 准备开启音频
    toOpenAudio(index) {
      if (JSON.stringify(this.videoData[index]) == '{}') {
        return
      }
      if (this.videoData[index].isOpenTalk) {
        this.$message({
          message: '请先关闭对讲',
          type: 'warning',
        })
        return
      } else {
        if (this.videoData[index].isOpenAudio) {
          // 关闭音频
          this.videoData[index].isOpenAudio = false
          this.videoWindow[index].CloseAudio()
          return
        } else {
          // 开启音频
          this.videoData[index].isOpenAudio = true
          this.videoWindow[index].OpenAudio()
        }
      }
    },
    // 准备开启喊话
    toOpenCall(index) {
      // 需判断是否有视频窗口，若无视频窗口则不能开启对讲，点击无反应
      if (JSON.stringify(this.videoData[index]) == '{}') {
        return
      }
      if (this.videoData[index].isOpenTalk) {
        this.$message({
          message: '请先关闭对讲',
          type: 'warning',
        })
        return
      } else {
        if (this.videoData[index].isOpenCall) {
          // 再次点击关闭喊话
          this.videoData[index].isOpenCall = false
          this.closeCall()
          return
        } else {
          // 开启喊话
          this.GetWSAudioAddress(index)
        }
      }
    },
    // 准备开启对讲
    async toOpenTalk(index) {
      // 需判断是否有视频窗口，若无视频窗口则不能开启对讲，点击无反应
      if (JSON.stringify(this.videoData[index]) == '{}') {
        return
      }
      if (this.videoData[index].isOpenTalk) {
        //再次点击关闭对讲
        this.videoData[index].isOpenTalk = false
        this.closeTalk()
      } else {
        if (this.videoData[index].isOpenCall) {
          // 关闭喊话
          this.videoData[index].isOpenCall = false
          await this.closeCall()
        }
        if (this.videoData[index].isOpenAudio) {
          // 关闭音频
          this.videoData[index].isOpenAudio = false
          await this.videoWindow[index].CloseAudio()
        }
        // 开启对讲
        this.GetWSVIDEOAddress(index)
      }
    },
    // 关闭对讲
    closeTalk() {
      var that = this
      that.talkMediaRecorder.CloseTalk()
    },
    // 关闭喊话
    closeCall() {
      var that = this
      that.callMediaRecorder.CloseCall()
    },
    // 开启对讲
    OpenTalk(wsPath, index) {
      var that = this
      var constraints = { audio: true, noiseSuppression: true }
      // 调用硬件
      navigator.mediaDevices
        .getUserMedia(constraints)
        .then(function (mediaStream) {
          var customParams = {
            containerOrId: 'videoBox' + index,
            // containerOrId: "videoBox0",
            callback: that.H5CallBack,
          }
          // 对讲实例化对象
          that.talkMediaRecorder = new H5Live.Talk(mediaStream, customParams)
          var options = {
            puid: that.videoData[index].puid,
            idx: index,
            // idx: 0,
            streamType: 'REALTIME',
            wsPath,
            type: 'OA',
          }
          // 开始对讲
          that.talkMediaRecorder.OpenTalk(options)
          // 已开始对讲标记
          that.videoData[index].isOpenTalk = true
        })
        .catch(function (err) {
          console.log('talkErr', err)
        })
    },
    // 开启喊话
    OpenCall(wsPath, index) {
      var that = this
      // 调用硬件
      var constraints = { audio: true, noiseSuppression: true }
      navigator.mediaDevices
        .getUserMedia(constraints)
        .then(function (mediaStream) {
          var customParams = {
            containerOrId: 'videoBox' + index,
            // containerOrId: "videoBox0",
            callback: that.H5CallBack,
          }
          // 喊话实例化对象
          that.callMediaRecorder = new H5Live.Call(mediaStream, customParams)
          var options = {
            // puid: that.puid,
            puid: that.videoData[index].puid,
            idx: index,
            // idx: 0,
            streamType: 'REALTIME',
            wsPath,
            type: 'OA',
          }
          // 开始喊话
          that.callMediaRecorder.OpenCall(options)
          // 开始喊话标记
          that.videoData[index].isOpenCall = true
        })
        .catch(function (err) {
          console.log('callErr', err)
        })
    },
    //开启本地录像
    OpenRecord(index) {
      // 需判断是否有视频窗口，若无视频窗口则不能开启录像，点击无反应
      if (JSON.stringify(this.videoData[index]) == '{}') {
        return
      }

      // this.isOpenRecord = !this.isOpenRecord;
      this.videoData[index].isOpenRecord = this.videoData[index].isOpenRecord
        ? false
        : true
      this.isActived = index

      var param = {
        sessionID: this.sessionID,
      }
      // if(this.isOpenRecord){
      this.videoWindow[index].OpenRecord(param)
      // }else{
      // this.GetPTZSpeed();
      // }
    },
    //关闭本地录像
    GetPTZSpeed() {
      var param = {
        sessionID: this.sessionID,
        puid: this.puid, //需要操作的设备PUID
        resIdx: 0, //需要操作的设备云台通道号（索引）
      }
      var that = this
      Ajax.SendAjax('GetPTZSpeed', param, function (rv) {
        if (rv.errorCode == '0x0000') {
        } else {
          that.errorMsg(rv.errorCode)
        }
      })
    },
    // 关闭本地录像
    closeRecord(index) {
      this.videoData[index].isOpenRecord = false
      this.videoWindow[index].CloseRecord()
    },
    //本地抓拍
    Snapshot(index) {
      // 没有视频窗口则没反应
      if (JSON.stringify(this.videoData[index]) == '{}') {
        return
      }

      var param = {
        imageType: '', //图片类型，默认为image/png
        saveAsName: 'Snapshot-' + new Date().getTime(), //图片名称
      }
      this.videoWindow[index].Snapshot(param)
    },
    // 云台控住
    PTZControl(type) {
      var param = {
        sessionID: this.sessionID,
        puid: this.puid, //需要操作的设备PUID
        ptzIdx: 1, //需要操作的设备云台通道号（索引）
        ptzAction: type, //需要操作的云台命令；云台命令请参考PTZDirection
      }
      var that = this
      Ajax.SendAjax('PTZControl', param, function (rv) {
        if (rv.errorCode == '0x0000') {
          that.$message({
            message: '云台操作成功',
            type: 'success',
          })
        } else {
          that.errorMsg(rv.errorCode)
        }
      })
    },
    // 点击树结构
    handleNodeClick(item) {
      if (item.online == '0') {
        this.$message({
          message: '设备' + item.name + '不在线',
          type: 'warning',
        })
      } else {
        // 在线
        // 若无视频窗口在播放

        // 若有视频窗口在播放
        // 1 先看选中的视频窗口是否有视频在播放
        // 2 若有视频在播放，则提示该窗口已有视频在播放
        // 3 若无视频在播放，则在该窗口播放视频

        for (var i = 0; i < this.videoData.length; i++) {
          if (item.puid == this.videoData[i].puid) {
            this.$message({
              message: '摄像头Camera已在播放同一视频',
              type: 'warning',
            })
            return
          }
        }

        //获取子节点
        this.ForkPUResourceNodes(item.puid, item.name)
        this.puid = item.puid
      }
    },
    // 本地录像列表
    GetH5LocalRecordList(index) {
      this.index = index
      this.dialogVisible = true

      // 获取开始和结束时间
      var now = new Date()
      var year = now.getFullYear() //得到年份
      var month = now.getMonth() //得到月份
      var date = now.getDate() //得到日期
      var hour = now.getHours() //得到小时
      var minu = now.getMinutes() //得到分钟
      var sec = now.getSeconds() //得到秒

      var beginTime =
        year +
        '-' +
        add0(month + 1) +
        '-' +
        add0(date - 1) +
        ' ' +
        add0(hour) +
        ':' +
        add0(minu) +
        ':' +
        add0(sec)
      var endTime =
        year +
        '-' +
        add0(month + 1) +
        '-' +
        add0(date) +
        ' ' +
        add0(hour) +
        ':' +
        add0(minu) +
        ':' +
        add0(sec)

      function add0(num) {
        return num < 10 ? '0' + num : num
      }

      var param = {
        sessionID: this.sessionID,
        // puid: "", //非必传，传了查单个设备，不传查所有设备
        beginTime: beginTime, //开始时间UTC
        endTime: endTime, //结束时间UTC
        offset: 0, //分页查询偏移量（从offset设定条数开始查询）
        count: 1000, //分页查询偏移量（查询count设置的条数）
      }
      var that = this
      Ajax.SendAjax('GetH5LocalRecordList', param, function (rv) {
        if (rv.errorCode == '0x0000') {
          that.tableData = rv.content.reslist
        } else {
          that.errorMsg(rv.errorCode)
        }
      })
    },
    // 关闭
    cancel() {
      this.dialogVisible = false
    },
    // 刷新
    refresh() {
      this.GetH5LocalRecordList(this.index)
    },
    // 云台速度
    SetPTZSpeed() {
      var param = {
        sessionID: this.sessionID,
        puid: this.puid, //需要操作的设备PUID
        resIdx: 0, //需要操作的设备云台通道号（索引）
        value: this.ptzspeed, //云台速度
      }
      var that = this
      Ajax.SendAjax('SetPTZSpeed', param, function (rv) {
        if (rv.errorCode == '0x0000') {
          that.$message({
            message: '操作成功',
            type: 'success',
          })
        } else {
          that.errorMsg(rv.errorCode)
        }
      })
    },
    // 获取文件名称
    formatterName(row, column) {
      const fileLen = row.FilePathName.lastIndexOf('/') // 取到文件名开始到最后一个点的长度
      const fileNameLen = row.FilePathName.length // 取到文件名长度
      const fileName = row.FilePathName.substring(fileLen + 1, fileNameLen) // 截
      if (fileName.length > 30) {
        return fileName.substring(0, 30) + '...'
      } else {
        return fileName
      }
    },
    //下载MP4
    downLoad(row) {
      window.open(row.HttpRequestURL)
    },
    // 抛错
    errorMsg(errorCode) {
      switch (errorCode) {
        case '0x0000':
          // $.messager.alert("操作提示","0x0000 成功","info",function(){});
          break
        case '0X0001':
          this.$message({
            type: 'error',
            message: '0X0001 失败',
          })
          break
        case '0x0002':
          this.$message({
            type: 'error',
            message: '0x0002 抛出异常',
          })
          break
        case '0x0010':
          this.$message({
            type: 'error',
            message: '0x0010 系统已登录',
          })
          break
        case '0x0011':
          this.$message({
            type: 'error',
            message: '0x0011 系统未登录',
          })
          break
        case '0x0012':
          this.$message({
            type: 'error',
            message: '0x0012 超过最大连接数',
          })
          break
        case '0x0020':
          this.$message({
            type: 'error',
            message: '0x0020 请求Action出错',
          })
          break
        case '0x0021':
          this.$message({
            type: 'error',
            message: '0x0021 请求Action未知',
          })
          break
        case '0x0022':
          this.$message({
            type: 'error',
            message: '0x0022 请求Action不存在',
          })
          break
        case '0x0030':
          this.$message({
            type: 'error',
            message: '0x0030 请求content出错',
          })
          break
        case '0x0031':
          this.$message({
            type: 'error',
            message: '0x0031 请求content内容为空',
          })
          break
        case '0x0032':
          this.$message({
            type: 'error',
            message: '0x0032 请求content不存在',
          })
          break
        case '0x0033':
          this.$message({
            type: 'error',
            message: '0x0033 offset过大',
          })
          break
        case '0x0040':
          this.$message({
            type: 'error',
            message: '0x0040 参数不合法',
          })
          break
        case '0x0050':
          this.$message({
            type: 'error',
            message: '0x0050 MYSQL数据库连接实例对象失败',
          })
          break
        case '0x0051':
          this.$message({
            type: 'error',
            message: '0x0051 MYSQL数据库操作失败',
          })
          break
        case '0x0060':
          this.$message({
            type: 'error',
            message: '0x0060 WebService请求地址错误',
          })
          break
        case '0x0061':
          this.$message({
            type: 'error',
            message: '0x0061 WebService密码验证错误',
          })
          break
        case '0x0062':
          this.$message({
            type: 'error',
            message: '0x0062 WebService响应失败',
          })
          break
        case '0x0063':
          this.$message({
            type: 'error',
            message: '0x0063 WebService参数验证失败',
          })
          break
        case '0x0064':
          this.$message({
            type: 'error',
            message: '0x0064 WebService对象未实例化',
          })
          break
        case '0x1000':
          this.$message({
            type: 'error',
            message: '0x1000 登录失败',
          })
          break
        case '0x1001':
          this.$message({
            type: 'error',
            message: '0x1001 登录超时',
          })
          break
        case '0x1010':
          this.$message({
            type: 'error',
            message: '0x1010 登录用户名格式错误',
          })
          break
        case '0x1011':
          this.$message({
            type: 'error',
            message: '0x1011 登录用户名不存在',
          })
          break
        case '0x1012':
          this.$message({
            type: 'error',
            message: '0x1012 登录密码错误',
          })
          break
        case '0x1013':
          this.$message({
            type: 'error',
            message: '0x1013 登录用户名参数不合法',
          })
          break
        case '0x1014':
          this.$message({
            type: 'error',
            message: '0x1014 登录超过最大连接数',
          })
          break
        case '0x1020':
          this.$message({
            type: 'error',
            message: '0x1020 SESSION错误',
          })
          break
        case '0x1021':
          this.$message({
            type: 'error',
            message: '0x1021 SESSION失效',
          })
          break
        case '0x1022':
          this.$message({
            type: 'error',
            message: '0x1022 SESSION长度不合法',
          })
          break
        case '0x2000':
          this.$message({
            type: 'error',
            message: '0x2000 XML发送至远程服务器失败',
          })
          break
        case '0x2001':
          this.$message({
            type: 'error',
            message: '0x2001 XML报文解析失败',
          })
          break
        case '0x2002':
          this.$message({
            type: 'error',
            message: '0x2002 XML返回错误',
          })
          break
        case '0x2003':
          this.$message({
            type: 'error',
            message: '0x2003 XML发送OPTID错误',
          })
          break
        case '0x2004':
          this.$message({
            type: 'error',
            message: '0x2004 XML报文NU错误',
          })
          break
      }
    },
    // 视频回调
    H5CallBack(response) {
      try {
        switch (response.action) {
          case 'ws.open':
            switch (response.type) {
              case 'video':
                // 视频打开
                break
              case 'vod':
                break
              case 'call':
                break
              case 'talk':
                console.log('talk1')
                break
            }
            break
          case 'ws.close':
            switch (response.type) {
              case 'video':
                // 视频已关闭
                break
              case 'vod':
                break
              case 'call':
                break
              case 'talk':
                console.log('talk2')
                break
            }
            break
          case 'ws.error':
            switch (response.type) {
              case 'video':
                break
              case 'vod':
                break
              case 'call':
                break
              case 'talk':
                break
            }
            break
          case 'stream.start':
            switch (response.type) {
              case 'video':
                break
              case 'audio':
                break
              case 'vod':
                break
              case 'call':
                break
              case 'talk':
                // playTalking = true;
                break
            }
            break
          case 'stream.stop':
            switch (response.type) {
              case 'video':
                break
              case 'audio':
                break
              case 'vod':
                // playRecording = false;
                break
              case 'call':
                break
              case 'talk':
                // playTalking = false;
                break
            }
            break
        }
      } catch (e) {
        // excep('H5CallBack', e);
      }
    },
    // 点击视频窗口
    clickBox(index) {
      this.i = index
      //  是否有此序号，有则不添加
      if (this.videoArr.indexOf(index) < 0) {
        this.videoArr.push(index)
      }
      console.log(this.videoArr)
    },
  },
}
</script>

<style lang="less" scoped>
.mainCon {
  padding: 0;
  // top: 196px;
  height: calc(100% - 67px);
}
.leftBox {
  width: 295px;
  height: 100%;
  float: left;
  .title {
    background-color: #0eb7a7;
    padding-left: 10px;
    height: 36px;
    line-height: 36px;
    width: 100%;
    color: #fff;
  }
  .cm-videomodules-leftbox-ptzbox {
    height: 250px;
    width: 100%;
    padding: 10px;
  }
  .cm-videomodules-leftbox-ptzbox-direction {
    background: url(../../../static/img/project/ptzbox-direction.png);
    background-repeat: no-repeat;
    margin-top: 20px;
    width: 141px;
    height: 141px;
    float: left;
    .up {
      background: url();
      background-position: 0 18px;
      width: 18px;
      height: 18px;
      position: relative;
      top: 15px;
      left: 63px;
      cursor: pointer;
      &:hover {
        background-position: 0 0;
      }
    }
    .center {
      width: 113px;
      height: 18px;
      position: relative;
      top: 44px;
      left: 15px;
      .left {
        background: url();
        background-position: 18px 18px;
        width: 18px;
        height: 18px;
        float: left;
        cursor: pointer;
        &:hover {
          background-position: 18px 0;
        }
      }
      .right {
        background: url();
        background-position: 36px 18px;
        width: 18px;
        height: 18px;
        float: right;
        cursor: pointer;
        &:hover {
          background-position: 36px 0;
        }
      }
    }
    .bottom {
      background: url();
      background-position: 54px 18px;
      width: 18px;
      height: 18px;
      position: relative;
      top: 73px;
      left: 63px;
      cursor: pointer;
      &:hover {
        background-position: 54px 0;
      }
    }
  }
  .cm-videomodules-leftbox-ptzbox-features {
    width: 129px;
    height: 165px;
    float: left;
    margin: 2px;
    .video-label {
      width: 100%;
      height: 32px;
      line-height: 32px;
      text-align: left;
      padding-left: 25px;
      color: #333;
      font-family: Microsoft YaHei;
      font-weight: 400;
      font-size: 14px;
    }
    .video-features {
      width: 72px;
      height: 22px;
      line-height: 30px;
      margin-left: 40px;
      .features-left {
        width: 36px;
        height: 22px;
        background: url();
        background-position: 0 0;
        background-repeat: no-repeat;
        line-height: 30px;
        float: left;
        cursor: pointer;
        &:hover {
          background-position: 0 -22px;
        }
      }
      .features-right {
        width: 36px;
        height: 22px;
        background: url();
        background-position: -36px 0;
        background-repeat: no-repeat;
        line-height: 30px;
        float: left;
        cursor: pointer;
        &:hover {
          background-position: -36px -22px;
        }
      }
    }
  }
  .cm-videomodules-leftbox-ptzbox-speedbox {
    position: relative;
    top: 20px;
    left: 5px;
    float: left;
    width: 100%;
    height: 30px;
    .video-label {
      position: absolute;
      top: 1px;
      left: 0;
      width: 75px;
      height: 30px;
      line-height: 30px;
      vertical-align: middle;
      text-align: left;
      font-family: Microsoft YaHei;
      font-weight: 400;
      font-size: 14px;
    }
    .video-ptzspeed-box {
      position: absolute;
      top: 0;
      left: 85px;
      width: 170px;
      height: 25px;
      line-height: 25px;
      vertical-align: middle;
    }
  }
}
.rightBox {
  width: calc(100% - 295px);
  padding-left: 5px;
  height: 100%;
  float: left;
  background: #f5f7fa;
}
.windowgroup {
  height: calc(100% - 66px);
  ul {
    height: 100%;
    li {
      position: relative;
      // outline-color: #fbb93f;
      // outline-style: solid;
      // outline-width: 2px;
      // border: 4px solid #fbb93f;
      .videoBox {
        width: 100%;
        height: 100%;
        background: #1a1a1a;
      }
      .cm-videomodule-videomessage {
        width: 100%;
        height: 40px;
        line-height: 40px;
        position: absolute;
        left: 0;
        top: 0;
        background-color: rgba(0, 0, 0, 0.25);
        background-color: hsla(0, 0%, 100%, 0.3);
        -webkit-box-sizing: content-box;
        box-sizing: content-box;
        outline: 0 !important;
        .cm-videomodule-videomessage-message {
          float: left;
          width: 75%;
          height: 40px;
          line-height: 40px;
          vertical-align: middle;
          text-indent: 5px;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
          color: #fff;
          font-family: Microsoft YaHei;
          font-size: 14px;
          margin-left: 10px;
        }
        .h5c-icons-lineHeight {
          line-height: 40px;
          margin-right: 10px;
          cursor: pointer;
          float: right;
          i {
            font-size: 24px;
            color: rgb(255, 255, 255);
          }
        }
      }
      .cm-videomodule-videocontrol {
        width: 100%;
        height: 40px;
        line-height: 40px;
        position: absolute;
        left: 0;
        bottom: 0;
        background-color: rgba(0, 0, 0, 0.25);
        background-color: hsla(0, 0%, 100%, 0.3);
        -webkit-box-sizing: content-box;
        box-sizing: content-box;
        outline: 0 !important;
        .h5c-icons-lineHeight {
          float: left;
          line-height: 40px;
          margin-left: 10px;
          cursor: pointer;
          i {
            font-size: 24px;
            color: rgb(255, 255, 255);
          }
        }
        // .h5c-icons-lineHeight:nth-of-type(1) {
        //   float: right;
        //   margin-right: 10px;
        // }
        .h5c-icons-floatRight {
          float: right;
          margin-right: 10px;
        }
      }
    }
    .currentClass {
      border: 4px solid #fbb93f;
    }
    .oneClass {
      height: 100%;
    }
    .fourClass {
      float: left;
      height: calc(50% - 4px);
      width: calc(50% - 3px);
    }
    .fourClass:nth-of-type(2n) {
      float: right;
    }
    .fourClass:nth-of-type(3),
    .fourClass:nth-of-type(4) {
      margin-top: 8px;
    }
    .nineClass {
      float: left;
      height: calc(33.33% - 4px);
      width: calc(33.33% - 3px);
    }
    .nineClass:nth-of-type(2),
    .nineClass:nth-of-type(8) {
      margin: 0 3px;
    }
    .nineClass:nth-of-type(4),
    .nineClass:nth-of-type(6) {
      margin: 4px 0;
    }
    .nineClass:nth-of-type(5) {
      margin: 4px 3px;
    }
    .sixteenClass {
      float: left;
      height: calc(25% - 4px);
      width: calc(25% - 4px);
    }
    .sixteenClass:nth-of-type(2n) {
      margin: 0 4px;
    }
    .sixteenClass:nth-of-type(5),
    .sixteenClass:nth-of-type(6),
    .sixteenClass:nth-of-type(7),
    .sixteenClass:nth-of-type(8),
    .sixteenClass:nth-of-type(9),
    .sixteenClass:nth-of-type(10),
    .sixteenClass:nth-of-type(11),
    .sixteenClass:nth-of-type(12) {
      margin: 4px 0;
    }
    .sixteenClass:nth-of-type(6) {
      margin: 4px 4px;
    }
    .sixteenClass:nth-of-type(7) {
      margin-right: 4px;
    }
    .sixteenClass:nth-of-type(10) {
      margin: 4px 4px;
    }
    .sixteenClass:nth-of-type(11) {
      margin-right: 4px;
    }
    .sixteenClass:nth-of-type(5),
    .sixteenClass:nth-of-type(6),
    .sixteenClass:nth-of-type(7),
    .sixteenClass:nth-of-type(8) {
      margin-bottom: 0;
    }
  }
}
.btngroup {
  height: 66px;
  padding: 10px;
  background: #fff;
  .btnBox li {
    float: left;
    margin-right: 10px;
    width: 46px;
    height: 46px;
    background: url();
    background-repeat: no-repeat;
    cursor: pointer;
  }
  .btnBox li:nth-of-type(1) {
    background-position: 0 -46px;
  }
  .btnBox li:nth-of-type(2) {
    background-position: -46px -46px;
  }
  .btnBox li:nth-of-type(3) {
    background-position: -92px -46px;
  }
  .btnBox li:nth-of-type(4) {
    background-position: -138px -46px;
  }
  .btnBox .active:nth-of-type(1) {
    background-position: 0 0;
  }
  .btnBox .active:nth-of-type(2) {
    background-position: -46px 0;
  }
  .btnBox .active:nth-of-type(3) {
    background-position: -92px 0;
  }
  .btnBox .active:nth-of-type(4) {
    background-position: -138px 0;
  }
}

.treeBox {
  height: calc(100% - 286px);
  .treeCon {
    height: calc(100% - 36px);
    overflow-y: auto;
  }
}

.redIcon {
  color: red !important;
}

.pvideo-window-state {
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  margin-top: -30px;
  margin-left: auto;
  margin-right: auto;
  padding: 20px;
  color: hsla(0, 0%, 100%, 0.8);
  font-size: 14px;
  text-align: center;
  line-height: 25px;
  vertical-align: middle;
  font-family: Microsoft YaHei;
}
</style>
